from exts import db
from common import constant
from app.order.model_mixin import OrderModelMixin
from common.base_model import BasicModelMixin, CompanyMixin, CreateMixin, UpdateMixin, DeleteMixin
from common import errors
from app.storage.storage_record.model import StorageRecord
from app.storage.storage_flow.model import StorageFlow
from common.constant import OrderStatus, OrderType


class TransferOrder(BasicModelMixin, db.Model, OrderModelMixin, CompanyMixin, CreateMixin, UpdateMixin, DeleteMixin):
    __tablename__ = 'transfer_order'

    from_warehouse_id = db.Column(db.Integer, db.ForeignKey('warehouse.id'))
    from_warehouse = db.relationship("Warehouse", foreign_keys='TransferOrder.from_warehouse_id')

    to_warehouse_id = db.Column(db.Integer, db.ForeignKey('warehouse.id'))
    to_warehouse = db.relationship("Warehouse", foreign_keys='TransferOrder.to_warehouse_id')

    order_skus = db.relationship("TransferOrderSku", back_populates='transfer_order',
                                 cascade="all, delete, delete-orphan")

    def save_draft(self, order_skus_json, image_ids, **kwargs):
        self.transfer_draft_status()
        # 更新order
        self.update(**kwargs)
        # 更新 order_sku
        for order_sku in self.order_skus:
            order_sku.hard_delete()  # 先删
        for order_sku_json in order_skus_json:
            # 获取当前库存，填入 from_before_num, to_before_num
            from_storage_record = StorageRecord.query.filter_by(
                warehouse_id=self.from_warehouse_id, sku_id=order_sku_json["sku_id"], unit_id=order_sku_json['unit_id']
            ).first()
            if from_storage_record:
                order_sku_json["from_before_num"] = from_storage_record.num
            else:
                order_sku_json["from_before_num"] = 0
            to_storage_record = StorageRecord.query.filter_by(
                warehouse_id=self.to_warehouse_id, sku_id=order_sku_json["sku_id"], unit_id=order_sku_json['unit_id']
            ).first()
            if to_storage_record:
                order_sku_json["to_before_num"] = to_storage_record.num
            else:
                order_sku_json["to_before_num"] = 0
            TransferOrderSku.create(order_id=self.id, **order_sku_json)  # 后增

        # 更新images
        self.update_images(image_ids)
        db.session.commit()

    def update_images(self, image_ids):
        self.update_images_by_belong_type(image_ids, constant.FileBelongType.TRANSFER_ORDER)

    def submit(self):
        """入库"""
        self.status = OrderStatus.SUCCESS  # 修改order状态
        self.update_warehouse_record()  # 更新库存
        self.create_warehouse_flow()  # 创建库存流水
        db.session.commit()

    def revoke(self):
        """回退入库，回退财务"""
        if self.status != OrderStatus.SUCCESS:
            raise errors.BadRequestError('无法撤销，只有已完成单据可撤销！')
        self.status = OrderStatus.REVOKE  # 修改order状态
        self.revoke_warehouse_record()  # 回退库存
        self.delete_warehouse_flow()  # 删除库存流水
        db.session.commit()

    def update_warehouse_record(self):
        """盘点， 直接修改数量, 不修改成本单价"""
        for order_sku in self.order_skus:
            # 出库仓库减少库存数量
            from_storage_record = StorageRecord.query.filter_by(
                warehouse_id=self.from_warehouse_id, sku_id=order_sku.sku_id, unit_id=order_sku.unit_id
            ).first()
            if from_storage_record is None:
                from_storage_record = StorageRecord.create(
                    warehouse_id=self.from_warehouse_id, sku_id=order_sku.sku_id, unit_id=order_sku.unit_id,
                    commit=True
                )
            from_storage_record.num -= order_sku.num
            # 入库仓库增加库存数量
            to_storage_record = StorageRecord.query.filter_by(
                warehouse_id=self.to_warehouse_id, sku_id=order_sku.sku_id, unit_id=order_sku.unit_id
            ).first()
            if to_storage_record is None:
                to_storage_record = StorageRecord.create(
                    warehouse_id=self.to_warehouse_id, sku_id=order_sku.sku_id, unit_id=order_sku.unit_id,
                    commit=True
                )
            to_storage_record.num += order_sku.num

    def revoke_warehouse_record(self):
        """调拨撤销 修改"""
        for order_sku in self.order_skus:
            from_storage_record = StorageRecord.query.filter_by(
                warehouse_id=self.from_warehouse_id, sku_id=order_sku.sku_id, unit_id=order_sku.unit_id
            ).first()
            from_storage_record.num += order_sku.before_num
            to_storage_record = StorageRecord.query.filter_by(
                warehouse_id=self.to_warehouse_id, sku_id=order_sku.sku_id, unit_id=order_sku.unit_id
            ).first()
            to_storage_record.num -= order_sku.before_num

    def create_warehouse_flow(self):
        for order_sku in self.order_skus:
            # 盘点前数量 在 save_draft 时会从数据库中取出
            StorageFlow.create(
                warehouse_id=self.from_warehouse_id, sku_id=order_sku.sku_id, unit_id=order_sku.unit_id,
                order_type=OrderType.TRANSFER, order_id=self.id, num=-order_sku.num,
            )
            StorageFlow.create(
                warehouse_id=self.to_warehouse_id, sku_id=order_sku.sku_id, unit_id=order_sku.unit_id,
                order_type=OrderType.TRANSFER, order_id=self.id, num=+order_sku.num,
            )

    def delete_warehouse_flow(self):
        for order_sku in self.order_skus:
            StorageFlow.query.filter_by(
                warehouse_id=self.from_warehouse_id, sku_id=order_sku.sku_id, unit_id=order_sku.unit_id,
                order_type=OrderType.TRANSFER, order_id=self.id,
            ).first().hard_delete()
            StorageFlow.query.filter_by(
                warehouse_id=self.to_warehouse_id, sku_id=order_sku.sku_id, unit_id=order_sku.unit_id,
                order_type=OrderType.TRANSFER, order_id=self.id,
            ).first().hard_delete()

    @classmethod
    def generate_order_sn_transfer(cls, prefix='DB'):
        return cls.generate_order_sn(prefix)


class TransferOrderSku(BasicModelMixin, db.Model, CompanyMixin, CreateMixin, DeleteMixin):
    __tablename__ = 'transfer_order_sku'

    id = db.Column(db.Integer, primary_key=True)
    order_id = db.Column(db.Integer, db.ForeignKey('transfer_order.id'))
    transfer_order = db.relationship("TransferOrder", foreign_keys="TransferOrderSku.order_id")

    sku_id = db.Column(db.Integer, db.ForeignKey('sku.id'))
    unit_id = db.Column(db.Integer, db.ForeignKey('unit.id'))

    num = db.Column(db.DECIMAL(20, constant.COMMON_DECIMAL), default=0)  # 数量
    from_before_num = db.Column(db.DECIMAL(20, constant.COMMON_DECIMAL), default=0)  # 调拨前数量，在调拨生效后保存, 用于查看
    to_before_num = db.Column(db.DECIMAL(20, constant.COMMON_DECIMAL), default=0)

    sku = db.relationship("Sku")
    unit = db.relationship("Unit")
